<template>
  <section class="dialog">
    <el-dialog draggable :close-on-click-modal="false" width="80%" destroy-on-close align-center lock-scroll
      :model-value="visible" @update:modelValue="change">
      <section class="content">
        <div>
          <section class="search">
            <div>
              <img src="local-media://icons/search.png" alt="">
              <input type="text" v-model="searchText" placeholder="搜索用户昵称">
              <img src="local-media://deleteIcon.png" alt="" name="delete" @click="searchText = ''"
                v-show="(searchText.length > 0)" style="cursor: pointer; ">
            </div>
            <button>搜索</button>
          </section>

          <nav class="navs" v-if="(searchType !== 2)">
            <span @click="(selectIndex = index)" v-for="(row, index) in list"
              :class="selectIndex === index ? 'active' : null">{{ row }}</span>
          </nav>
        </div>
        <section class="search_box">
          <div class="search_result">
            <template v-if="(result.length > 0)">
              <ul v-for="first in result">
                <li class="title" v-if="(first.content.length > 0)">{{ first?.title }}</li>
                <li class="item" v-for="row in first.content" @click="selectGroupAndUser($event, row)">
                  <el-avatar style="flex-shrink: 0;" :size="46" :src="row?.portrait" />
                  <div>
                    <span>{{ row?.name || row?.groupName || row?.nickName }}</span>
                    <span>{{ row?.remark }}</span>
                  </div>
                  <span class="radio">
                    <template v-if="(searchType === 1)">
                      <img src="local-media://person.png" alt="" v-if="row?.nickName" class="person_img">
                    </template>
                    <template v-else>
                      <el-radio v-if="(checked(row) > -1)" />
                      <el-radio :label="row?.groupId || row.userId" v-else />
                    </template>
                  </span>
                </li>
              </ul>
            </template>
            <section class="nodata"
              v-if="(searchType === 1 && result[0].content.length == 0 && result[1].content.length == 0)">
              <img src="local-media://no_result.png" alt="" />
              <p>没有找到相关结果</p>
            </section>
          </div>
          <div class="submit_block" v-if="(searchType !== 1)">
            <div class="nums">
              <span>已选择</span>
              <span style="margin-left: 5px;">{{ hasSelectItem?.length }}</span>
            </div>
            <section class="alllist noDrag">
              <div v-for="row in hasSelectItem" @click="selectGroupAndUser($event, row)">
                <el-avatar style="flex-shrink: 0;" :size="32" :src="(row?.portrait || row?.groupPortrait)" />
                <span class="names">{{ row?.name || row?.nickName || row?.groupName }}</span>
                <img src="local-media://deleteIcon.png" alt="">
              </div>
            </section>
            <section class="actions">
              <button @click="canceAction">取消</button>
              <button @click="submitInfo" :class="(hasSelectItem?.length < 2 && searchType === 2 ? 'stop' : null)">{{
              (selectMessages.length === 0 ? '创建群聊' : "转发")
              }}</button>
            </section>
          </div>
        </section>
        <el-popover width="270" v-model:visible="userDetail" placement="bottom-start" trigger="focus" virtual-triggering
          :virtual-ref="triggerRef" v-if="(searchType === 1)" :teleported="false" :hide-after="0" :show-arrow="false">
          <div>
            <FriendDetail v-if="selectCardInfo?.userId" :userId="selectCardInfo?.userId" sm
              @submit="userDetail = false" />
            <GroupDetail @submit="(userDetail = false)" sm :groupId="selectCardInfo?.groupId"
              v-if="selectCardInfo?.groupId" />
          </div>
        </el-popover>
      </section>
    </el-dialog>
  </section>
</template>
<script>
import { defineComponent, computed, ref, onMounted, watch, nextTick } from 'vue';
import { useStore } from 'vuex'
import { v4 as uuidv4 } from 'uuid';
import { bulkForwarding } from '@/tool/useWebsokect'
import { pinyin } from 'pinyin-pro'
import { createGroup } from '@/server/group'
import FriendDetail from '@/views/Friend/FriendPanner/FriendDetail'
import GroupDetail from '@/views/Friend/FriendPanner/GroupDetail'
export default defineComponent({
  components: {
    FriendDetail,
    GroupDetail
  },
  setup (props) {
    const selectIndex = ref(0)
    const list = [
      '全部',
      '联系人',
      '我的群聊',
    ]
    const store = useStore()
    const userInfo = computed(() => store.state.userInfo)
    const friend = computed(() => store.state.activePanners[3].data?.filter(r => r.userId !== userInfo.value.userId) || [])
    const group = computed(() => store.state.activePanners[0].data || [])
    const visible = computed(() => store.state.visible)

    const searchType = computed(() => store.state.searchType)
    const change = (value) => store.commit('saveDialogState', value)

    onMounted(() => {
      store.dispatch('getFriendByType', { index: 0 })
      store.dispatch('getFriendByType', { index: 3 })
    })

    const searchText = ref('')

    const result = computed(() => {
      const state = [
        [...friend.value, ...group.value],
        [...friend.value],
        [...group.value]
      ]
      let currentData = []
      if (searchType.value === 2) {
        currentData = state[1]
      }
      if (searchType.value === 1 || searchType.value === 3) {
        currentData = state[selectIndex.value]
      }

      if (!!searchText.value) {
        currentData = currentData?.filter(v => {
          const text = v.nickName || v.name
          return text.includes(searchText.value)
        })
      }

      const b = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

      const getdate = (trans, hasSort = true) => {
        const has = []
        const other = []
        trans.forEach((r) => {
          const text = r.nickName || r.name
          const p = pinyin(text, { pattern: 'first', toneType: 'none', type: 'array' })[0]
          if (b.includes(p.toLowerCase())) {
            const index = has.findIndex(s => s.title === p)
            index > -1 ? has[index].content?.push(r) : (has.push({ title: p, content: [r] }))
          } else {
            other.push(r)
          }
        })
        if (hasSort) {
          has.sort((s1, s2) => {
            const x1 = s1?.title.toUpperCase();
            const x2 = s2?.title.toUpperCase();
            if (x1 < x2) return -1
            if (x1 > x2) return 1
            return 0
          })
        }
        return {
          has,
          other: {
            title: "#",
            content: other
          }
        }
      }

      if (searchType.value === 2) {
        //创建群聊
        const friendBase = getdate(currentData)
        return [...friendBase.has, friendBase.other]
      }

      if (searchType.value === 3) {
        //转发
        const data = getdate(currentData)
        return [...data.has, data.other]
      }

      if (searchType.value === 1) {
        //普通搜索
        return currentData?.reduce((sum, current) => {
          const state = [...sum]
          if (current?.groupId) state[1].content.push(current)
          if (current?.userId) state[0].content.push(current)
          return state
        }, [{ title: "联系人", content: [] }, { title: "我的群聊", content: [] }])
      }
    })


    const hasSelectItem = computed(() => store.state.searchSelectItem)
    const selectMessages = computed(() => store.state.selectMessages)

    const checked = (row) => {
      return hasSelectItem.value?.findIndex(item => {
        if (item?.userId && row?.userId) return row.userId === item.userId
        if (item?.groupId && row?.groupId) return row.groupId === item.groupId
        return false
      })
    }

    const triggerRef = computed(() => ({
      getBoundingClientRect: () => position.value
    }))
    const position = ref({
      top: 0,
      left: 0,
      bottom: 0,
      right: 0
    })

    const userDetail = ref(false)
    const selectCardInfo = ref()
    const selectGroupAndUser = async (e, row) => {
      if (searchType.value === 1) {
        setTimeout(() => {
          position.value = DOMRect.fromRect({
            width: 0,
            height: 0,
            x: e.clientX,
            y: e.clientY,
          })
          selectCardInfo.value = row
          userDetail.value = true
        }, 100);
        e.preventDefault()
        return
      }
      const index = hasSelectItem.value?.findIndex(item => {
        if (item?.userId && row?.userId) return row.userId === item.userId
        if (item?.groupId && row?.groupId) return row.groupId === item.groupId
        return false
      })
      const lastState = [...hasSelectItem.value]
      if (index > -1) {
        lastState.splice(index, 1)
      } else {
        lastState.push({ ...row })
      }
      store.commit('saveSearchSelectItem', lastState)
      e.preventDefault()
    }

    watch(visible, (newState) => {
      if (!newState) {
        store.commit('saveSearchSelectItem', [])
        selectCardInfo.value = null
        searchText.value = ''
        userDetail.value = false
      }
    })

    const canceAction = () => {
      store.commit('saveSelectMessages', [])
      store.commit('saveDialogState', false)
      store.commit('saveSearchSelectItem', [])
      store.commit('saveOpenChecked', false)
    }

    const submitInfo = async () => {
      const waitTarget = [...store.state.searchSelectItem]
      if (searchType.value === 3) {
        const waitMsg = store.state.selectMessages

        const msgdata = waitMsg.map((row) => {
          const msgId = uuidv4()
          const item = { ...row }
          try {
            // 防止引用消息嵌套
            const content = JSON.parse(item.content)
            if (content?.content) {
              item.content = content?.content
            }
          } catch (error) {

          }
          const customInitMsg = {
            msgId,
            pushType: "MSG",
            timestamp: new Date().getTime(),
            msgContent: {
              content: item?.content,
              msgType: item?.msgType,
            },
            fromInfo: {
              nickName: userInfo?.value?.nickName,
              portrait: userInfo?.value?.portrait,
              userId: userInfo?.value?.userId,
              userType: userInfo?.value?.userType || '',
            },
            groupInfo: {}
          }
          return customInitMsg
        })
        const state = JSON.parse(JSON.stringify(msgdata))
        const msg = waitTarget.map(item => {
          const res = state.map(row => {
            row.msgContent.top = item.top
            row.msgContent.disturb = item.disturb
            row.groupInfo = {
              nickName: item?.groupName,
              portrait: item?.groupPortrait,
              userId: item?.groupId,
            }
            if (!item?.groupId) row.groupInfo = {}
            return row
          })
          const { groupId, userId } = item
          const s = { ...item, waitMsg: res }
          if (groupId) s.groupInfo = { userId: groupId }
          if (userId) s.fromInfo = { userId }
          return { ...s, waitMsg: res }
        })
        const res = await bulkForwarding(msg, store)
      }
      if (searchType.value === 2) {
        // 创建群聊
        const params = {
          list: waitTarget.map(row => row.userId)
        }
        const res = await createGroup(params)
        if (res) canceAction()
      }
    }

    return {
      canceAction,
      submitInfo,
      hasSelectItem,
      visible,
      change,
      result,
      selectIndex,
      friend,
      group,
      searchText,
      checked,
      selectGroupAndUser,
      list,
      selectMessages,
      searchType,
      position,
      triggerRef,
      userDetail,
      selectCardInfo
    }
  }
})
</script>

<style scoped lang="less">
.content {
  height: 70vh;
  display: flex;
  flex-direction: column;

  .search {
    padding: 0 40px;
    margin-top: 7px;
    display: flex;



    >div {
      height: 38px;
      background: #F7F7F7;
      width: 100%;
      border-radius: 18px;
      opacity: 0.5;
      border: 1px solid #ECECEC;
      display: flex;
      align-items: center;
      display: flex;
      justify-content: space-between;
      padding: 0 7px;
      border-top-right-radius: 0;
      border-bottom-right-radius: 0;

      >input {
        flex: 1;
        outline: none;
        border: none;
        background: #F7F7F7;
        color: #242424;
      }

    }

    >button {
      width: 90px;
      height: 38px;
      background: linear-gradient(356deg, #009BFD 8%, #00E8E8 100%);
      outline: none;
      border: none;
      border-radius: 18px;
      border-top-left-radius: 0;
      border-bottom-left-radius: 0;
      font-weight: 500;
      color: #FFFFFF;
      cursor: pointer;
    }
  }

  .navs {
    padding-bottom: 10px;
    padding-top: 18px;
    width: 100%;
    padding-left: 56px;
    font-size: 14px;

    font-weight: 400;
    color: #787878;
    line-height: 16px;
    display: flex;
    border-bottom: 1px solid #eff3fc;
    height: 50px;

    >span {
      margin-right: 15px;
      padding-bottom: 8px;
      letter-spacing: 1px;
      cursor: pointer;
      position: relative;

      &.active {
        &::after {
          position: absolute;
          bottom: 0;
          left: 0;
          content: "";
          background: linear-gradient(356deg, #009BFD 8%, #00E8E8 100%);
          height: 2px;
          width: 100%;
        }
      }
    }
  }

  .search_box {
    flex: 1;
    display: flex;
    height: calc(70vh - 96px);
  }

  .search_result {
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-app-region: no-drag;
    position: relative;
    flex: 1;

    &::-webkit-scrollbar {
      display: none;
    }

    .title {
      padding-left: 60px;
      font-size: 14px;

      font-weight: 400;
      color: #787878;
      padding-top: 16px;
      padding-bottom: 16px;
      position: sticky;
      top: 0;
      background-color: #fff;
      z-index: 1;
      text-transform: uppercase;

      &.solid {
        border-top: 1px solid #eff3fc;
        margin-top: 16px;
      }
    }

    .item {
      height: 68px;
      padding-left: 60px;
      width: 100%;
      display: flex;
      align-items: center;

      .person_img {
        display: none;
        transition: 1s linear;
      }

      &:hover {
        .person_img {
          display: inline-block;
        }
      }

      >div {
        display: flex;
        flex-direction: column;
        height: 48px;
        justify-content: space-between;
        padding: 5px 0;
        margin-left: 10px;

        >span {
          &:first-child {
            font-size: 14px;

            font-weight: 400;
            color: rgba(36, 36, 36, 1);
            line-height: 16px;
          }

          &:last-child {
            font-size: 14px;

            font-weight: 400;
            color: #787878;
            line-height: 16px;
          }
        }
      }

      .group_name {
        justify-content: center;
      }

      &:hover {
        background: #F7F7F7;
      }

      .radio {
        margin-left: auto;
        padding-right: 60px;

        &:deep(.el-radio__label) {
          display: none;
        }
      }
    }
  }

  .submit_block {
    width: 60%;
    flex-shrink: 0;
    border-left: 1px solid #EDF1FB;
    display: flex;
    flex-direction: column;
    height: 100%;
    padding-bottom: 47px;

    .nums {
      display: flex;
      margin-left: 16px;
      margin-top: 16px;
      font-size: 14px;

      font-weight: 400;
      color: #242424;
      line-height: 16px;
    }

    .alllist {
      display: grid;
      grid-template-columns: repeat(auto-fill, 180px);
      grid-gap: 10px 10px;
      padding: 16px 12px;
      justify-content: space-evenly;
      align-content: flex-start;
      flex: 1;
      overflow-y: auto;
      margin-bottom: 12px;

      &::-webkit-scrollbar {
        display: none;
      }

      >div {
        border-radius: 100px 100px 100px 100px;
        background: #F7F7F7;
        display: flex;
        align-items: center;
        padding: 6px 8px;
        height: 44px;

        .names {
          margin-left: 10px;
        }

        >img {
          margin-left: auto;
        }
      }
    }


    .actions {
      width: 100%;
      display: flex;
      justify-content: space-evenly;
      padding: 0 5%;
      height: 48px;
      margin-top: auto;



      >button {
        border: none;
        outline: none;
        width: 158px;
        height: 100%;
        border-radius: 60px 60px 60px 60px;
        opacity: 1;
        border: 1px solid #01D6EE;
        font-size: 20px;
        color: #05D9D9;
        background: #fff;
        cursor: pointer;

        &:last-child {
          font-weight: 400;
          color: #FFFFFF;
          background: linear-gradient(114deg, #009BFD 8%, #00E8E8 100%);
          box-shadow: 1px 9px 20px 0px rgba(142, 212, 237, 0.63);
        }

        &.stop {
          background: #999999 !important;
          box-shadow: none;
          border: none;
          pointer-events: none
        }
      }
    }
  }
}

.dialog {
  :deep(.el-dialog__body) {
    padding: 0
  }

  :deep(.el-popover) {
    border-radius: 14px;
  }
}

.nodata {
  margin: 100px auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  >p {
    font-size: 16px;

    font-weight: 400;
    color: #242424;
    margin-top: 28px;
  }
}
</style>
